#include <string.h>

#include <panel-applet.h>
#include <gtk/gtklabel.h>
#include <gtk/gtk.h>
#include <libgtkhtml/gtkhtml.h>
#include <libxml/xmlreader.h>
#include <sys/inotify.h>
#include <pthread.h>

char filename[200];
int fd;
pthread_t wait_thread;

HtmlDocument *doc;

GtkWidget *eventBox;
GtkWidget *appletBox;
GtkWidget *appletLabel;
GtkWidget *appletIcon;
GtkWidget *appletPopup;
GtkWidget *appletText;
GtkWidget *appletHtml;

PanelApplet *applet;

GdkColor textColor;
GdkColor flashColor;
GdkColor popupBgColor;

gboolean popupVisible = 0;

static int wait_on_change(char* target);
static void appletClicked();

#define FLASH_DURATION_MS 3000
#define FLASH_STEP_DURATION_MS 200
#define BUFFER_SIZE 8192
static void
example_applet_change_background(PanelApplet *applet,
        PanelAppletBackgroundType type,
        GdkColor *colour,
        GdkPixmap *pixmap);

static void flash_fg(GtkWidget* widget, GdkColor *origColor, GdkColor *flashColor) {
    int count = FLASH_DURATION_MS / FLASH_STEP_DURATION_MS;
    while (count-- > 0) {
        gtk_widget_modify_fg(widget, GTK_STATE_NORMAL, flashColor);
        usleep(FLASH_STEP_DURATION_MS * 1000);
        gtk_widget_modify_fg(widget, GTK_STATE_NORMAL, origColor);
        usleep(FLASH_STEP_DURATION_MS * 1000);
    }
}

static void setPopupVisible(gboolean visible) {
    if (!visible) {
        gtk_widget_hide_all(appletPopup);
    } else {
        gtk_widget_show_all(appletPopup);
        gtk_window_move(GTK_WINDOW(appletPopup), 500, 0);
    }

}

static gboolean
on_button_press(GtkWidget *event_box,
        GdkEventButton *event,
        gpointer data) {
    static int window_shown;
    static GtkWidget *window, *box, *image, *label;
    /* Don't react to anything other than the left mouse button;
       return FALSE so the event is passed to the default handler */
    if (event->button != 1)
        return FALSE;

    if (popupVisible) {
        setPopupVisible(0);
        popupVisible = 0;
    } else {
        setPopupVisible(1);
        popupVisible = 1;
    }

}

static void
processNode(xmlTextReaderPtr reader) {
    const xmlChar *name, *type, *text, *label, *icon, *popup, *html;
    name = xmlTextReaderConstName(reader);
    if (!strcmp(name, "Notification")) {
        type = xmlTextReaderGetAttribute(reader, "type");
        label = xmlTextReaderGetAttribute(reader, "label");
        text = xmlTextReaderGetAttribute(reader, "text");
        icon = xmlTextReaderGetAttribute(reader, "icon");
        popup = xmlTextReaderGetAttribute(reader, "popup");
        html = xmlTextReaderGetAttribute(reader, "html");
        if (label != 0)
            gtk_label_set_text(GTK_LABEL(appletLabel), label);
        if (text != 0) {
            //gtk_label_set_text(GTK_LABEL(appletText), text);
            //gtk_label_set_text(GTK_LABEL(appletText), "<a href='test.html'>hej</a>");
            gtk_widget_set_tooltip_text(appletBox, text);

        }
        if (html != 0) {

            FILE * pFile;
            char buffer[BUFFER_SIZE];
            int result;

            pFile = fopen(html, "r");
            result = fread(buffer, 1, BUFFER_SIZE, pFile);

            html_document_open_stream(doc, "text/html");
            html_document_write_stream(doc, buffer, strlen(buffer));
            html_document_close_stream(doc);
        }
        if (icon != 0) {
            gtk_image_set_from_file(GTK_IMAGE(appletIcon), icon);
        }
        if (popup != 0) {
            if (!strcmp(popup, "SHOW")) {
                setPopupVisible(1);
                popupVisible = 1;
            }
        }
        gtk_box_pack_start(GTK_BOX(appletBox), appletIcon, 1, 1, 0);
        if (!strcmp(type, "FLASH")) {
            flash_fg(appletLabel, &textColor, &flashColor);
        }
    }
}

static void
streamFile(const char *filename) {
    xmlTextReaderPtr reader;
    int ret;
    reader = xmlReaderForFile(filename, NULL, 0);
    if (reader != NULL) {
        ret = xmlTextReaderRead(reader);
        while (ret == 1) {
            processNode(reader);
            ret = xmlTextReaderRead(reader);
        }
        xmlFreeTextReader(reader);
    }
}

gchar *html = "<a href='http://www.gp.se'>test</a><br>test<br><table><tr><td>hej</td><td>då</td></tr></table>";

static void
link_clicked (HtmlDocument *doc, const gchar *url, gpointer view)
{
        xmlChar         command[256];
        sprintf(command, "gnome-open %s", url);
        system(command);
}

static gboolean
myexample_applet_fill(PanelApplet *a,
        const gchar *iid,
        gpointer data) {
    applet = a;
    // Make sure background is according to rest of panel (i.e. transparent)
    g_signal_connect(applet, "change-background", G_CALLBACK(example_applet_change_background), NULL);

    // Event box to get events
    eventBox = gtk_event_box_new();
    gtk_event_box_set_visible_window(GTK_EVENT_BOX(eventBox), 0);
    g_signal_connect(G_OBJECT(eventBox),
            "button_press_event",
            G_CALLBACK(on_button_press), 0);

    // Box to hold image and label
    appletBox = gtk_hbox_new(0, 0);
    appletIcon = gtk_image_new();

    appletPopup = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_default_size(GTK_WINDOW(appletPopup), 40, 20);
    gtk_window_set_decorated(GTK_WINDOW(appletPopup), 0);

    gdk_color_parse("yellow", &popupBgColor);
    gtk_widget_modify_bg(GTK_WIDGET(appletPopup), GTK_STATE_NORMAL, &popupBgColor);

    appletText = gtk_label_new("<a>Description</a>");
    gtk_label_set_justify(GTK_LABEL(appletText), GTK_JUSTIFY_LEFT);
    // gtk_container_add(GTK_CONTAINER(appletPopup), appletText);

    doc = html_document_new();


    g_signal_connect(G_OBJECT(doc), "link_clicked",
            G_CALLBACK(link_clicked), 0);


    html_document_open_stream(doc, "text/html");
    html_document_write_stream(doc, html, strlen(html));
    html_document_close_stream(doc);

    appletHtml = html_view_new();
    gtk_widget_set_size_request(GTK_WIDGET(appletHtml), 400, 200);
    html_view_set_document(HTML_VIEW(appletHtml), doc);
    html_view_set_magnification(HTML_VIEW(appletHtml), 1.0);

    gtk_container_add(GTK_CONTAINER(appletPopup), appletHtml);
    gtk_box_pack_start(GTK_BOX(appletBox), appletIcon, 0, 0, 0);

    fd = inotify_init();

    sprintf(filename, "%s/.notifier.xml", getenv("HOME"));

    if (strcmp(iid, "OAFIID:GNOME_FileChangeNotifier") != 0)
        return FALSE;
    appletLabel = gtk_label_new("WAIT ON CHANGE");
    gtk_label_set_single_line_mode(GTK_LABEL(appletLabel), 1);

    gtk_box_pack_start(GTK_BOX(appletBox), appletLabel, 0, 0, 0);
    gtk_container_add(GTK_CONTAINER(eventBox), appletBox);
    gtk_container_add(GTK_CONTAINER(applet), eventBox);

    gdk_color_parse("black", &textColor);
    gdk_color_parse("red", &flashColor);

    gtk_widget_modify_fg(appletLabel, GTK_STATE_NORMAL, &textColor);
    gtk_widget_show_all(GTK_WIDGET(applet));

    streamFile(filename);
    pthread_create(&wait_thread, NULL, &wait_on_change, filename);
    return TRUE;
}

#define BUFF_SIZE ((sizeof(struct inotify_event)+FILENAME_MAX)*1024)

static int wait_on_change(char* target) {
    int fd;
    int wd; /* watch descriptor */

    fd = inotify_init();
    if (fd < 0) {
        //handle_error (errno);
        return 1;
    }

    wd = inotify_add_watch(fd, target, IN_MODIFY);
    if (wd < 0) {
        //handle_error (errno);
        return 1;
    }

    char buff[BUFF_SIZE] = {0};
    ssize_t len, i = 0;
    while (1) {
        len = read(fd, buff, BUFF_SIZE);
        // File has been changed, parse it
        streamFile(target);
    }


    return 0;
}

static void
example_applet_change_background(PanelApplet *applet,
        PanelAppletBackgroundType type,
        GdkColor *colour,
        GdkPixmap *pixmap) {
    GtkRcStyle *rc_style;
    GtkStyle *style;

    /* reset style */
    gtk_widget_set_style(GTK_WIDGET(applet), NULL);
    rc_style = gtk_rc_style_new();
    gtk_widget_modify_style(GTK_WIDGET(applet), rc_style);
    gtk_rc_style_unref(rc_style);

    switch (type) {
        case PANEL_NO_BACKGROUND:
            break;
        case PANEL_COLOR_BACKGROUND:
            gtk_widget_modify_bg(GTK_WIDGET(applet),
                    GTK_STATE_NORMAL, colour);
            break;
        case PANEL_PIXMAP_BACKGROUND:
            style = gtk_style_copy(GTK_WIDGET(applet)->style);

            if (style->bg_pixmap[GTK_STATE_NORMAL])
                g_object_unref(style->bg_pixmap[GTK_STATE_NORMAL]);

            style->bg_pixmap[GTK_STATE_NORMAL] = g_object_ref(pixmap);
            gtk_widget_set_style(GTK_WIDGET(applet), style);
            g_object_unref(style);
            break;
    }
}



PANEL_APPLET_BONOBO_FACTORY("OAFIID:GNOME_FileChangeNotifier_Factory",
        PANEL_TYPE_APPLET,
        "File Change Notifier Applet",
        "0",
        myexample_applet_fill,
        NULL);
